package com.hippo.core.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.UUID;

/**
 * 测试用例生成工具类
 *
 * @author hippo
 */
public class CaseGenerator {

    /**
     * @param type 控件类型
     * @return 根据控件英文名返回操作命令
     */
    public String mappingLabel(String type) {
        String value = "";
        switch (type) {
            case "input":
                value = "输入框输入";
                break;
            case "radio":
                value = "单选框选中";
                break;
            case "checkbox":
                value = "复选框选中";
                break;
            case "select":
                value = "下拉框选中";
                break;
            case "cascader":
                value = "级联选择器选中";
                break;
            case "datePicker":
                value = "日期选择器选中";
                break;
            case "timePicker":
                value = "日期时间选择器选中";
                break;
        }
        return value;
    }

    /**
     * @param preconditionObj 前置条件对象
     * @return 通用的前置条件
     */
    public String generatePrecondition(JSONObject preconditionObj) {
        return "1." + preconditionObj.getString("name") + "已登录系统" + "\n"
                + "2.已进入到" + preconditionObj.getString("module") + "页面";
    }

    /**
     * @param requireList  必填字段数组
     * @param functionName 功能名称
     * @param operateId    新建1，编辑2
     * @return 符合生成规则的必填项用例数组
     */
    public ArrayList<HashMap<String, Object>> generateRequire(ArrayList<JSONObject> requireList, String functionName, String operateId) {
        ArrayList<HashMap<String, Object>> list = new ArrayList<>();
        HashMap<String, Object> map = new HashMap<>();
        ArrayList<String> preconditionList = new ArrayList<>();
        ArrayList<String> stepList = new ArrayList<>();
        ArrayList<String> resultList = new ArrayList<>();
        map.put("caseName", functionName + "_必填参数_置空");
        String label = "";
        for (int i = 0; i < requireList.size(); i++) {
            label += (requireList.get(i).getString("name") + "、");
        }
        String result = operateId.equals("1") ? "2.对话框内显示" + label.substring(0, label.length() - 1) + "等控件" : "2.对话框内表单内容回显正确";
        preconditionList.add("\n3." + label.substring(0, label.length() - 1) + "已被设置值");
        stepList.add("点击\"" + functionName + "\"按钮");
        resultList.add("1.成功打开" + functionName + "对话框\n" + result + "\n3.界面显示符合UI设计规范要求");
        for (int i = 0; i < requireList.size(); i++) {
            stepList.add("设置【" + requireList.get(i).getString("name") + "】" + mappingLabel(requireList.get(i).getString("type")).substring(0, mappingLabel(requireList.get(i).getString("type")).length() - 2) + "的值为空，光标失焦");
            resultList.add("设置失败，显示校验提示");
        }
        map.put("precondition", preconditionList);
        map.put("step", stepList);
        map.put("result", resultList);
        list.add(map);
        return list;
    }

    /**
     * @param requireList  必填字段数组
     * @param functionName 功能名称
     * @param operateId    新建1，编辑2
     * @return 符合生成规则的输入框用例数组
     */
    public ArrayList<HashMap<String, Object>> generateInput(ArrayList<JSONObject> requireList, String functionName, String operateId) throws Exception {
        DataGenerator fakerData = new DataGenerator();
        ArrayList<HashMap<String, Object>> list = new ArrayList<>();
        ArrayList<String> caseNameList = new ArrayList<>();
        caseNameList.add("_非法参数_特殊字符");
        caseNameList.add("_非法参数_脚本函数");
        caseNameList.add("_非法参数_空格");
        caseNameList.add("_唯一性校验_重复值");
        caseNameList.add("_长度校验_最大长度_最小长度");
        caseNameList.add("_长度校验_最大长度加1_最小长度减1");
        String label = "";
        for (int i = 0; i < requireList.size(); i++) {
            label += (requireList.get(i).getString("name") + "、");
        }
        String result = operateId.equals("1") ? "2.对话框内显示" + label.substring(0, label.length() - 1) + "等控件" : "2.对话框内表单内容回显正确";
        for (int i = 0; i < caseNameList.size(); i++) {
            HashMap<String, Object> map = new HashMap<>();
            ArrayList<String> stepList = new ArrayList<>();
            ArrayList<String> resultList = new ArrayList<>();
            ArrayList<String> preconditionList = new ArrayList<>();
            stepList.add("点击\"" + functionName + "\"按钮");
            resultList.add("1.成功打开" + functionName + "对话框\n" + result + "\n3.界面显示符合UI设计规范要求");
            map.put("caseName", functionName + caseNameList.get(i));
            if (i == 0) { //_非法参数_特殊字符
                for (int n = 0; n < requireList.size(); n++) {
                    preconditionList.add(String.format("\n3.%s等字段输入的字符没有特殊格式要求", label.substring(0, label.length() - 1)));
                    stepList.add("【" + requireList.get(n).getString("name") + "】输入框输入\"~!@#$%^&*()_+{}|[]\\:\"<>?;',./?;:\"，光标失焦");
                    resultList.add("输入成功，无校验提示");
                }
            } else if (i == 1) { //_非法参数_脚本函数
                for (int n = 0; n < requireList.size(); n++) {
                    preconditionList.add(String.format("\n3.%s等字段输入的字符没有特殊格式要求", label.substring(0, label.length() - 1)));
                    stepList.add("【" + requireList.get(n).getString("name") + "】输入框输入\"<script>alert(\"abc\")</script>、doucment.write(\"abc\")、<b>hello</b>\"，光标失焦");
                    resultList.add("输入成功，无校验提示");
                }
            } else if (i == 2) { //_非法参数_空格
                for (int n = 0; n < requireList.size(); n++) {
                    preconditionList.add(String.format("\n3.%s等字段输入的字符没有特殊格式要求", label.substring(0, label.length() - 1)));
                    stepList.add("【" + requireList.get(n).getString("name") + "】输入框输入\"\u3000\u3000 空 \u3000\u3000 格 \u3000\u3000\"，光标失焦");
                    resultList.add("输入成功，无校验提示，保存后去除首尾空格");
                }
            } else if (i == 3) { //_唯一性校验_重复值
                for (int n = 0; n < requireList.size(); n++) {
                    if (requireList.get(n).getBoolean("repeat")) {
                        preconditionList.add(String.format("\n3.%s等字段输入的字符没有特殊格式要求\n4.该字段数据库已存在值\"xxx\"", label.substring(0, label.length() - 1)));
                        stepList.add("【" + requireList.get(n).getString("name") + "】输入框输入\"重复值（xxx）\"，光标失焦");
                        resultList.add("输入成功，无校验提示，保存时提示\"" + requireList.get(n).getString("name") + "不能重复\"");
                    }
                }
            } else if (i == 4) { //_长度校验_最大值|最小值
                for (int n = 0; n < requireList.size(); n++) {
                    Integer maxLength = requireList.get(n).getInteger("maxLength");
                    Integer minLength = requireList.get(n).getInteger("minLength");
                    String maxLengthStr = fakerData.getValueByMethodName("com.github.javafaker.Number", "digits",
                            "int", String.valueOf(maxLength)).toString();
                    String minLengthStr = fakerData.getValueByMethodName("com.github.javafaker.Number", "digits",
                            "int", String.valueOf(minLength)).toString();
                    preconditionList.add(String.format("\n3.%s等字段输入的字符没有特殊格式要求", label.substring(0, label.length() - 1)));
                    stepList.add("【" + requireList.get(n).getString("name") + "】输入框输入\"" + maxLengthStr + "\" 或 \" " + minLengthStr + "\" ，光标失焦");
                    resultList.add("输入成功，无校验提示");
                }
            } else if (i == 5) { //_长度校验_最长值+1
                for (int n = 0; n < requireList.size(); n++) {
                    Integer maxLength = requireList.get(n).getInteger("maxLength") + 1;
                    Integer minLength = requireList.get(n).getInteger("minLength") - 1;
                    String maxLengthStr = fakerData.getValueByMethodName("com.github.javafaker.Number", "digits",
                            "int", String.valueOf(maxLength)).toString();
                    String minLengthStr = fakerData.getValueByMethodName("com.github.javafaker.Number", "digits",
                            "int", String.valueOf(minLength)).toString();
                    preconditionList.add(String.format("\n3.%s等字段输入的字符没有特殊格式要求", label.substring(0, label.length() - 1)));
                    stepList.add("【" + requireList.get(n).getString("name") + "】输入框输入\"" + maxLengthStr + "\" 或 \" " + minLengthStr + "\" ，光标失焦");
                    resultList.add("输入失败，显示校验提示");
                }
            }
            map.put("precondition", preconditionList);
            map.put("step", stepList);
            map.put("result", resultList);
            if (stepList.size() > 0 & preconditionList.size() > 0) {
                list.add(map);
            }
        }
        return list;
    }

    /**
     * @param requireList  必填字段数组
     * @param functionName 功能名称
     * @param operateId    新建1，编辑2
     * @return 符合生成规则的计数框用例数组
     */
    public ArrayList<HashMap<String, Object>> generateInputNumber(ArrayList<JSONObject> requireList, String functionName, String operateId) {
        ArrayList<HashMap<String, Object>> list = new ArrayList<>();
        ArrayList<String> caseNameList = new ArrayList<>();
        caseNameList.add("_数值大小校验_最大值_最小值");
        caseNameList.add("_数值大小校验_最大值加1_最小值减1");
        caseNameList.add("_非法参数_开头有0");
        String label = "";
        for (int i = 0; i < requireList.size(); i++) {
            label += (requireList.get(i).getString("name") + "、");
        }
        String result = operateId.equals("1") ? "2.对话框内显示" + label.substring(0, label.length() - 1) + "等控件" : "2.对话框内表单内容回显正确";
        for (int i = 0; i < caseNameList.size(); i++) {
            HashMap<String, Object> map = new HashMap<>();
            ArrayList<String> preconditionList = new ArrayList<>();
            ArrayList<String> stepList = new ArrayList<>();
            ArrayList<String> resultList = new ArrayList<>();
            stepList.add("点击\"" + functionName + "\"按钮");
            resultList.add("1.成功打开" + functionName + "对话框\n" + result + "\n3.界面显示符合UI设计规范要求");
            map.put("caseName", functionName + caseNameList.get(i));
            if (i == 0) { //_数值大小校验_最大值_最小值
                for (int n = 0; n < requireList.size(); n++) {
                    Integer maxValue = requireList.get(n).getInteger("maxValue");
                    Integer minValue = requireList.get(n).getInteger("minValue");
                    preconditionList.add("");
                    stepList.add("【" + requireList.get(n).getString("name") + "】计数框输入\"" + maxValue + "\" 或 \" " + minValue + "\" ，光标失焦");
                    resultList.add("输入成功，无校验提示");
                }
            } else if (i == 1) {
                for (int n = 0; n < requireList.size(); n++) {
                    Integer maxValue = requireList.get(n).getInteger("maxValue") + 1;
                    Integer minValue = requireList.get(n).getInteger("minValue") - 1;
                    preconditionList.add("");
                    stepList.add("【" + requireList.get(n).getString("name") + "】计数框输入\"" + maxValue + "\" 或 \" " + minValue + "\" ，光标失焦");
                    resultList.add("输入失败，显示校验提示");
                }
            } else if (i == 2) { //_非法参数_开头有0
                for (int n = 0; n < requireList.size(); n++) {
                    Integer maxValue = requireList.get(n).getInteger("maxValue");
                    preconditionList.add("");
                    stepList.add("【" + requireList.get(n).getString("name") + "】计数框输入\"000" + maxValue + "\"，光标失焦");
                    resultList.add("输入成功，回显的是" + maxValue);
                }
            }
            map.put("precondition", preconditionList);
            map.put("step", stepList);
            map.put("result", resultList);
            list.add(map);
        }
        return list;
    }

    /**
     * @param requireList  必填字段数组
     * @param functionName 功能名称
     * @param operateId    新建1，编辑2
     * @return 符合生成规则的日期选择器用例数组
     */
    public ArrayList<HashMap<String, Object>> generateDatePicker(ArrayList<JSONObject> requireList, String functionName, String operateId) throws Exception {
        ArrayList<HashMap<String, Object>> list = new ArrayList<>();
        ArrayList<String> caseNameList = new ArrayList<>();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
        DataGenerator dataGenerator = new DataGenerator();
        caseNameList.add("_日期选择_无限制");
        caseNameList.add("_单个日期_可选值");
        caseNameList.add("_单个日期_不可选值");
        caseNameList.add("_日期范围_可选值");
        caseNameList.add("_日期范围_不可选值");
        String label = "";
        for (int i = 0; i < requireList.size(); i++) {
            label += (requireList.get(i).getString("name") + "、");
        }
        String result = operateId.equals("1") ? "2.对话框内显示" + label.substring(0, label.length() - 1) + "等控件" : "2.对话框内表单内容回显正确";
        for (int i = 0; i < caseNameList.size(); i++) {
            HashMap<String, Object> map = new HashMap<>();
            ArrayList<String> preconditionList = new ArrayList<>();
            ArrayList<String> stepList = new ArrayList<>();
            ArrayList<String> resultList = new ArrayList<>();
            stepList.add("点击\"" + functionName + "\"按钮");
            resultList.add("1.成功打开" + functionName + "对话框\n" + result + "\n3.界面显示符合UI设计规范要求");
            map.put("caseName", functionName + caseNameList.get(i));
            if (i == 0) { //_日期选择_无限制
                for (int n = 0; n < requireList.size(); n++) {
                    if (!requireList.get(n).getBoolean("restriction")) {
                        if (requireList.get(n).getString("type").equals("datePicker")) {
                            simpleDateFormat.applyPattern("yyyy-MM-dd");
                            preconditionList.add("");
                            stepList.add("【" + requireList.get(n).getString("name") + "】日期选择器选择\"" + simpleDateFormat.format(new Date()) + "\"");
                            resultList.add("选择成功，查看日期选择器面板，面板高亮选中的值，无校验提示");
                        } else {
                            simpleDateFormat.applyPattern("yyyy-MM-dd HH:mm:ss");  //其中的a时am和pm的标记，如果不加a则不会显示是上午还是下午
                            preconditionList.add("");
                            stepList.add("【" + requireList.get(n).getString("name") + "】日期时间选择器选择\"" + simpleDateFormat.format(new Date()) + "\"");
                            resultList.add("选择成功，查看日期时间选择器面板，面板高亮选中的值，无校验提示");
                        }
                    }
                }
            } else if (i == 1) { //_单个日期_可选值
                for (int n = 0; n < requireList.size(); n++) {
                    if (requireList.get(n).getString("type").equals("datePicker")) {
                        if (requireList.get(n).getBoolean("restriction") & requireList.get(n).getString("chooseDate").equals("1")) {
                            simpleDateFormat.applyPattern("yyyy-MM-dd");
                            Date date = simpleDateFormat.parse(requireList.get(n).getString("singleDate"));    // 选中的天数
                            Date preDate = new Date(date.getTime() - 24 * 60 * 60 * 1000); //前一天
                            Date nextDate = new Date(date.getTime() + 24 * 60 * 60 * 1000); //后一天
                            preconditionList.add("");
                            if (requireList.get(n).getString("comparator").equals(">")) {
                                stepList.add("【" + requireList.get(n).getString("name") + "】日期选择器选择\"" + simpleDateFormat.format(nextDate) + "\"");
                            } else if (requireList.get(n).getString("comparator").equals("=")) {
                                stepList.add("【" + requireList.get(n).getString("name") + "】日期选择器选择\"" + simpleDateFormat.format(date) + "\"");
                            } else if (requireList.get(n).getString("comparator").equals("<")) {
                                stepList.add("【" + requireList.get(n).getString("name") + "】日期选择器选择\"" + simpleDateFormat.format(preDate) + "\"");
                            }
                            resultList.add("选择成功，查看日期选择器面板，面板高亮选中的值，无校验提示");
                        }
                    } else {
                        if (requireList.get(n).getBoolean("restriction") & requireList.get(n).getString("chooseTime").equals("1")) {
                            simpleDateFormat.applyPattern("yyyy-MM-dd HH:mm:ss");  //其中的a时am和pm的标记，如果不加a则不会显示是上午还是下午
                            String singleTime = requireList.get(n).getString("singleTime");
                            Date date = simpleDateFormat.parse(singleTime.substring(0, 10) + " " + singleTime.substring(11, 19));    // 选中的天数
                            Date preDate = new Date(date.getTime() - 24 * 60 * 60 * 1000); //前一天
                            Date nextDate = new Date(date.getTime() + 24 * 60 * 60 * 1000); //后一天
                            preconditionList.add("");
                            if (requireList.get(n).getString("comparator").equals(">")) {
                                stepList.add("【" + requireList.get(n).getString("name") + "】日期时间选择器选择\"" + simpleDateFormat.format(nextDate) + "\"");
                            } else if (requireList.get(n).getString("comparator").equals("=")) {
                                stepList.add("【" + requireList.get(n).getString("name") + "】日期时间选择器选择\"" + simpleDateFormat.format(date) + "\"");
                            } else if (requireList.get(n).getString("comparator").equals("<")) {
                                stepList.add("【" + requireList.get(n).getString("name") + "】日期时间选择器选择\"" + simpleDateFormat.format(preDate) + "\"");
                            }
                            resultList.add("选择成功，查看日期时间选择器面板，面板高亮选中的值，无校验提示");
                        }
                    }
                }
            } else if (i == 2) { //_单个日期_不可选值
                for (int n = 0; n < requireList.size(); n++) {
                    if (requireList.get(n).getString("type").equals("datePicker")) {
                        if (requireList.get(n).getBoolean("restriction") & requireList.get(n).getString("chooseDate").equals("1")) {
                            simpleDateFormat.applyPattern("yyyy-MM-dd");
                            Date date = simpleDateFormat.parse(requireList.get(n).getString("singleDate"));    // 选中的天数
                            Date preDate = new Date(date.getTime() - 24 * 60 * 60 * 1000); //前一天
                            Date nextDate = new Date(date.getTime() + 24 * 60 * 60 * 1000); //后一天
                            preconditionList.add("");
                            if (requireList.get(n).getString("comparator").equals(">")) {
                                stepList.add("【" + requireList.get(n).getString("name") + "】日期选择器选择\"" + simpleDateFormat.format(preDate) + " 或 " + simpleDateFormat.format(date) + "\"");
                                resultList.add("选中失败，面板中\"" + simpleDateFormat.format(date) + " 或 " + simpleDateFormat.format(preDate) + "\"已置灰");
                            } else if (requireList.get(n).getString("comparator").equals("=")) {
                                stepList.add("【" + requireList.get(n).getString("name") + "】日期选择器选择\"" + simpleDateFormat.format(preDate) + " 或 " + simpleDateFormat.format(nextDate) + "\"");
                                resultList.add("选中失败，面板中\"" + simpleDateFormat.format(date) + " 或 " + simpleDateFormat.format(preDate) + "\"已置灰");
                            } else if (requireList.get(n).getString("comparator").equals("<")) {
                                stepList.add("【" + requireList.get(n).getString("name") + "】日期选择器选择\"" + simpleDateFormat.format(date) + " 或 " + simpleDateFormat.format(nextDate) + "\"");
                                resultList.add("选中失败，面板中\"" + simpleDateFormat.format(date) + " 或 " + simpleDateFormat.format(preDate) + "\"已置灰");
                            }
                        }
                    } else {
                        if (requireList.get(n).getBoolean("restriction") & requireList.get(n).getString("chooseTime").equals("1")) {
                            simpleDateFormat.applyPattern("yyyy-MM-dd HH:mm:ss");  //其中的a时am和pm的标记，如果不加a则不会显示是上午还是下午
                            String singleTime = requireList.get(n).getString("singleTime");
                            Date date = simpleDateFormat.parse(singleTime.substring(0, 10) + " " + singleTime.substring(11, 19));    // 选中的天数
                            Date preDate = new Date(date.getTime() - 24 * 60 * 60 * 1000); //前一天
                            Date nextDate = new Date(date.getTime() + 24 * 60 * 60 * 1000); //后一天
                            preconditionList.add("");
                            if (requireList.get(n).getString("comparator").equals(">")) {
                                stepList.add("【" + requireList.get(n).getString("name") + "】日期时间选择器选择\"" + simpleDateFormat.format(preDate) + " 或 " + simpleDateFormat.format(date) + "\"");
                                resultList.add("选中失败，面板中\"" + simpleDateFormat.format(date) + " 或 " + simpleDateFormat.format(preDate) + "\"已置灰");
                            } else if (requireList.get(n).getString("comparator").equals("=")) {
                                stepList.add("【" + requireList.get(n).getString("name") + "】日期时间选择器选择\"" + simpleDateFormat.format(preDate) + " 或 " + simpleDateFormat.format(nextDate) + "\"");
                                resultList.add("选中失败，面板中\"" + simpleDateFormat.format(date) + " 或 " + simpleDateFormat.format(preDate) + "\"已置灰");
                            } else if (requireList.get(n).getString("comparator").equals("<")) {
                                stepList.add("【" + requireList.get(n).getString("name") + "】日期时间选择器选择\"" + simpleDateFormat.format(date) + " 或 " + simpleDateFormat.format(nextDate) + "\"");
                                resultList.add("选中失败，面板中\"" + simpleDateFormat.format(date) + " 或 " + simpleDateFormat.format(preDate) + "\"已置灰");
                            }
                        }
                    }
                }
            } else if (i == 3) { //_日期范围_可选值
                for (int n = 0; n < requireList.size(); n++) {
                    if (requireList.get(n).getString("type").equals("datePicker")) {
                        if (requireList.get(n).getBoolean("restriction") & requireList.get(n).getString("chooseDate").equals("2")) {
                            simpleDateFormat.applyPattern("yyyy-MM-dd");
                            Object valueByMethodName = dataGenerator.getValueByMethodName("customize.Date", "date", "date, date",
                                    String.valueOf(requireList.get(n).getJSONArray("datePicker").get(0)).substring(0, 10) + "," +
                                            String.valueOf(requireList.get(n).getJSONArray("datePicker").get(1)).substring(0, 10));
                            preconditionList.add("");
                            stepList.add("【" + requireList.get(n).getString("name") + "】日期选择器选择\"" + String.valueOf(valueByMethodName) + "\"");
                            resultList.add("选择成功，查看日期选择器面板，面板高亮选中的值，无校验提示");
                        }
                    } else {
                        if (requireList.get(n).getBoolean("restriction") & requireList.get(n).getString("chooseTime").equals("2")) {
                            simpleDateFormat.applyPattern("yyyy-MM-dd HH:mm:ss");  //其中的a时am和pm的标记，如果不加a则不会显示是上午还是下午
                            if (requireList.get(n).getBoolean("restriction") & requireList.get(n).getString("chooseTime").equals("2")) {
                                String startTime = String.valueOf(requireList.get(n).getJSONArray("timePicker").get(0));
                                String endTime = String.valueOf(requireList.get(n).getJSONArray("timePicker").get(1));
                                Object valueByMethodName = dataGenerator.getValueByMethodName("customize.Date", "datetime", "time, time",
                                        startTime.substring(0, 10) + " " + startTime.substring(11, 19) + "," +
                                                endTime.substring(0, 10) + " " + endTime.substring(11, 19));
                                preconditionList.add("");
                                stepList.add("【" + requireList.get(n).getString("name") + "】日期时间选择器选择\"" + String.valueOf(valueByMethodName) + "\"");
                                resultList.add("选择成功，查看日期选择器面板，面板高亮选中的值，无校验提示");
                            }
                        }
                    }
                }
            } else if (i == 4) { //_日期范围_不可选值
                for (int n = 0; n < requireList.size(); n++) {
                    if (requireList.get(n).getString("type").equals("datePicker")) {
                        simpleDateFormat.applyPattern("yyyy-MM-dd");
                        if (requireList.get(n).getBoolean("restriction") & requireList.get(n).getString("chooseDate").equals("2") & requireList.get(n).getJSONArray("datePicker").size() > 0) {
                            Date startDate = simpleDateFormat.parse(String.valueOf(requireList.get(n).getJSONArray("datePicker").get(0)));    // 选中的开始天数
                            Date endDate = simpleDateFormat.parse(String.valueOf(requireList.get(n).getJSONArray("datePicker").get(1)));    // 选中的结束天数
                            Date preDate = new Date(startDate.getTime() - 24 * 60 * 60 * 1000); //前一天
                            Date nextDate = new Date(endDate.getTime() + 24 * 60 * 60 * 1000); //后一天
                            preconditionList.add("");
                            stepList.add("【" + requireList.get(n).getString("name") + "】日期选择器选择\"" + simpleDateFormat.format(preDate) + " 或 " + simpleDateFormat.format(nextDate) + "\"");
                            resultList.add("选中失败，面板中\"" + simpleDateFormat.format(preDate) + " 或 " + simpleDateFormat.format(nextDate) + "\"已置灰");
                        }
                    } else {
                        simpleDateFormat.applyPattern("yyyy-MM-dd HH:mm:ss");  //其中的a时am和pm的标记，如果不加a则不会显示是上午还是下午
                        if (requireList.get(n).getBoolean("restriction") & requireList.get(n).getString("chooseTime").equals("2") & requireList.get(n).getJSONArray("timePicker").size() > 0) {
                            String startTime = String.valueOf(requireList.get(n).getJSONArray("timePicker").get(0));
                            String endTime = String.valueOf(requireList.get(n).getJSONArray("timePicker").get(1));
                            Date startDate = simpleDateFormat.parse(startTime.substring(0, 10) + " " + startTime.substring(11, 19));    // 选中的开始天数
                            Date endDate = simpleDateFormat.parse(endTime.substring(0, 10) + " " + endTime.substring(11, 19));    // 选中的结束天数
                            Date preDate = new Date(startDate.getTime() - 24 * 60 * 60 * 1000); //前一天
                            Date nextDate = new Date(endDate.getTime() + 24 * 60 * 60 * 1000); //后一天
                            preconditionList.add("");
                            stepList.add("【" + requireList.get(n).getString("name") + "】日期时间选择器选择\"" + simpleDateFormat.format(preDate) + " 或 " + simpleDateFormat.format(nextDate) + "\"");
                            resultList.add("选中失败，面板中\"" + simpleDateFormat.format(preDate) + " 或 " + simpleDateFormat.format(nextDate) + "\"已置灰");
                        }
                    }
                }
            }
            map.put("precondition", preconditionList);
            map.put("step", stepList);
            map.put("result", resultList);
            if (stepList.size() > 0 & preconditionList.size() > 0) {
                list.add(map);
            }
        }
        return list;
    }

    /**
     * @param requireList  必填字段数组
     * @param functionName 功能名称
     * @param operateId    新建1，编辑2
     * @return 符合生成规则的文件上传用例数组
     */
    public ArrayList<HashMap<String, Object>> generateUpload(ArrayList<JSONObject> requireList, String functionName, String operateId) {
        DataGenerator fakerData = new DataGenerator();
        ArrayList<HashMap<String, Object>> list = new ArrayList<>();
        ArrayList<String> caseNameList = new ArrayList<>();
        caseNameList.add("_上传文件_文件大小_0kb");
        caseNameList.add("_上传文件_文件大小_超出限制");
        caseNameList.add("_上传文件_文件类型_非要求类型");
        caseNameList.add("_上传文件_文件数量_超出限制");
        caseNameList.add("_上传文件_被打开的文件");
        caseNameList.add("_上传文件_手动输入存在的图片地址");
        caseNameList.add("_上传文件_手动输入不存在的图片地址");
        String label = "";
        for (int i = 0; i < requireList.size(); i++) {
            label += (requireList.get(i).getString("name") + "、");
        }
        String result = operateId.equals("1") ? "2.对话框内显示" + label.substring(0, label.length() - 1) + "等控件" : "2.对话框内表单内容回显正确";
        for (int i = 0; i < caseNameList.size(); i++) {
            HashMap<String, Object> map = new HashMap<>();
            ArrayList<String> stepList = new ArrayList<>();
            ArrayList<String> preconditionList = new ArrayList<>();
            ArrayList<String> resultList = new ArrayList<>();
            stepList.add("点击\"" + functionName + "\"按钮");
            resultList.add("1.成功打开" + functionName + "对话框\n" + result + "\n3.界面显示符合UI设计规范要求");
            map.put("caseName", functionName + caseNameList.get(i));
            if (i == 0) { //_上传文件_文件大小_0kb
                for (int n = 0; n < requireList.size(); n++) {
                    preconditionList.add("\n3.允许上传文件格式." + requireList.get(n).getJSONArray("fileFormat").get(0)
                            + "\n4.允许最大上传的文件数量为" + requireList.get(n).getInteger("maxNum")
                            + "个\n5.允许上传文件大小最大为" + requireList.get(n).getInteger("fileSize") + "Mb，最小不能是0kb");
                    stepList.add("【" + requireList.get(n).getString("name") + "】上传一个0kb的." + requireList.get(n).getJSONArray("fileFormat").get(0) + "文件");
                    resultList.add("上传失败，显示校验提示\"上传的文件不能为空\"");
                }
            } else if (i == 1) { //_上传文件_文件大小_超出限制
                for (int n = 0; n < requireList.size(); n++) {
                    preconditionList.add("\n3.允许上传文件格式." + requireList.get(n).getJSONArray("fileFormat").get(0)
                            + "\n4.允许最大上传的文件数量为" + requireList.get(n).getInteger("maxNum")
                            + "个\n5.允许上传文件大小最大为" + requireList.get(n).getInteger("fileSize") + "Mb，最小不能是0kb");
                    stepList.add("【" + requireList.get(n).getString("name") + "】上传一个" + (requireList.get(n).getInteger("fileSize") + 1) + "Mb的."
                            + requireList.get(n).getJSONArray("fileFormat").get(0) + "文件");
                    resultList.add("上传失败，显示校验提示\"上传的文件大小不能大于" + requireList.get(n).getInteger("fileSize") + "Mb\"");
                }
            } else if (i == 2) { //_上传文件_文件类型_非要求类型
                for (int n = 0; n < requireList.size(); n++) {
                    preconditionList.add("\n3.允许上传文件格式." + requireList.get(n).getJSONArray("fileFormat").get(0)
                            + "\n4.允许最大上传的文件数量为" + requireList.get(n).getInteger("maxNum")
                            + "个\n5.允许上传文件大小最大为" + requireList.get(n).getInteger("fileSize") + "Mb，最小不能是0kb");
                    stepList.add("【" + requireList.get(n).getString("name") + "】上传一个" + (requireList.get(n).getInteger("fileSize") - 0.1) + "Mb的.xmind文件");
                    resultList.add("上传失败，显示校验提示\"上传的文件类型不符合\"");
                }
            } else if (i == 3) { //_上传文件_文件数量_超出限制
                for (int n = 0; n < requireList.size(); n++) {
                    preconditionList.add("\n3.允许上传文件格式." + requireList.get(n).getJSONArray("fileFormat").get(0)
                            + "\n4.允许最大上传的文件数量为" + requireList.get(n).getInteger("maxNum")
                            + "个\n5.允许上传文件大小最大为" + requireList.get(n).getInteger("fileSize") + "Mb，最小不能是0kb");
                    stepList.add("【" + requireList.get(n).getString("name") + "】上传" + (requireList.get(n).getInteger("maxNum") + 1) + "个" + (requireList.get(n).getInteger("fileSize") - 0.1) + "Mb的."
                            + requireList.get(n).getJSONArray("fileFormat").get(0) + "文件");
                    resultList.add("上传失败，显示校验提示\"上传的文件数量不能超过" + requireList.get(n).getInteger("maxNum") + "个\"，或达到限制后上传按钮置灰");
                }
            } else if (i == 4) { //_上传文件_被打开的文件
                for (int n = 0; n < requireList.size(); n++) {
                    preconditionList.add("\n3.允许上传文件格式." + requireList.get(n).getJSONArray("fileFormat").get(0)
                            + "\n4.允许最大上传的文件数量为" + requireList.get(n).getInteger("maxNum")
                            + "个\n5.允许上传文件最大为" + requireList.get(n).getInteger("fileSize") + "Mb，最小不能是0kb");
                    stepList.add("【" + requireList.get(n).getString("name") + "】上传一个正被打开的" + (requireList.get(n).getInteger("fileSize") - 0.1) + "Mb的."
                            + requireList.get(n).getJSONArray("fileFormat").get(0) + "文件");
                    resultList.add("上传成功，无校验提示，已上传的列表显示该文件");
                }
            } else if (i == 5) { //_上传文件_手动输入存在的图片地址
                for (int n = 0; n < requireList.size(); n++) {
                    preconditionList.add("\n3.允许上传文件格式." + requireList.get(n).getJSONArray("fileFormat").get(0)
                            + "\n4.允许最大上传的文件数量为" + requireList.get(n).getInteger("maxNum")
                            + "个\n5.允许上传文件大小最大为" + requireList.get(n).getInteger("fileSize") + "Mb，最小不能是0kb");
                    stepList.add("点击【" + requireList.get(n).getString("name") + "】上传按钮，手动输入存在的图片地址");
                    resultList.add("上传成功，无校验提示，已上传的列表显示该文件");
                }
            } else if (i == 6) { //_上传文件_手动输入不存在的图片地址
                for (int n = 0; n < requireList.size(); n++) {
                    preconditionList.add("\n3.允许上传文件格式." + requireList.get(n).getJSONArray("fileFormat").get(0)
                            + "\n4.允许最大上传的文件数量为" + requireList.get(n).getInteger("maxNum")
                            + "个\n5.允许上传文件大小最大为" + requireList.get(n).getInteger("fileSize") + "Mb，最小不能是0kb");
                    stepList.add("点击【" + requireList.get(n).getString("name") + "】上传按钮，手动输入不存在的图片地址");
                    resultList.add("上传失败，显示校验提示\"请检查文件名是否正确，然后重试\"");
                }
            }
            map.put("precondition", preconditionList);
            map.put("step", stepList);
            map.put("result", resultList);
            if (stepList.size() > 0 & preconditionList.size() > 0) {
                list.add(map);
            }
        }
        return list;
    }

    /**
     * @param formObj      表单对象
     * @param functionName 功能名称
     * @param operateId    新建1，编辑2
     * @return 多种情况组合的用例
     * @throws Exception
     */
    public ArrayList<HashMap<String, Object>> groupFrom(JSONArray formObj, String functionName, String operateId) throws Exception {
        ArrayList<JSONObject> inputList = new ArrayList<>();
        ArrayList<JSONObject> inputNumberList = new ArrayList<>();
        ArrayList<JSONObject> datePickerList = new ArrayList<>();
        ArrayList<JSONObject> uploadList = new ArrayList<>();
        ArrayList<JSONObject> requireList = new ArrayList<>(); //是否必填arr
        ArrayList<HashMap<String, Object>> array = new ArrayList<>();
        formObj.forEach(item -> {
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(item));
            String type = jsonObject.getString("type");
            if (jsonObject.getBoolean("require")) {
                requireList.add(jsonObject);
            }
            if (type.equals("input")) {
                inputList.add(jsonObject);
            } else if (type.equals("inputNumber")) {
                inputNumberList.add(jsonObject);
            } else if (type.equals("datePicker") | type.equals("timePicker")) {
                datePickerList.add(jsonObject);
            } else if (type.equals("upload")) {
                uploadList.add(jsonObject);
            }
        });
        if (requireList.size() > 0) {
            array.addAll(generateRequire(requireList, functionName, operateId));
        }
        if (inputList.size() > 0) {
            array.addAll(generateInput(inputList, functionName, operateId));
        }
        if (inputNumberList.size() > 0) {
            array.addAll(generateInputNumber(inputNumberList, functionName, operateId));
        }
        if (datePickerList.size() > 0) {
            array.addAll(generateDatePicker(datePickerList, functionName, operateId));
        }
        if (uploadList.size() > 0) {
            array.addAll(generateUpload(uploadList, functionName, operateId));
        }
        return array;
    }

    /**
     * @param infoObj   表单对象
     * @param formObj   基本继续对
     * @param operateId 新建1，编辑2
     * @return 新建表单、编辑表单用例
     * @throws Exception
     */
    public ArrayList<HashMap<String, Object>> newEditForm(JSONObject infoObj, JSONArray formObj, String operateId) throws Exception {
        String functionName = infoObj.getString("name");
        String btnName = infoObj.getString("btnName");
        ArrayList<HashMap<String, Object>> lists = new ArrayList<>();
        HashMap<String, Object> map = new HashMap<>();
        ArrayList<String> stepLists = new ArrayList<>();
        ArrayList<String> resultLists = new ArrayList<>();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
        DataGenerator fakerData = new DataGenerator();
        // 多种情况组合的用例
        lists.addAll(groupFrom(formObj, functionName, operateId));
        // 正向操作的具体用例
        String label = "";
        for (int i = 0; i < formObj.size(); i++) {
            label += (JSONObject.parseObject(JSON.toJSONString(formObj.get(i))).getString("name") + "、");
        }
        String result = operateId.equals("1") ? "2.对话框内显示" + label.substring(0, label.length() - 1) + "等控件"
                : "2.对话框内表单内容回显正确";
        stepLists.add("点击\"" + functionName + "\"按钮");
        resultLists.add("1.成功打开" + functionName + "对话框\n" + result + "\n3.界面显示符合UI设计规范要求");
        formObj.forEach(item -> {
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(item));
            String name = jsonObject.getString("name");
            String type = jsonObject.getString("type");
            int fileSize = jsonObject.getInteger("fileSize");
            JSONArray fileFormat = jsonObject.getJSONArray("fileFormat");
            Boolean restriction = jsonObject.getBoolean("restriction");
            JSONArray datePicker = jsonObject.getJSONArray("datePicker");
            JSONArray timePicker = jsonObject.getJSONArray("timePicker");
            String comparator = jsonObject.getString("comparator");
            String singleDate = jsonObject.getString("singleDate");
            String singleTime = jsonObject.getString("singleTime");
            String value = jsonObject.getString("value");
            String valueString = "";
            if (value != "" & value != null) {
                for (int i = 0; i < value.split(",").length; i++) {
                    if (i == value.split(",").length - 1) {
                        valueString += value.split(",")[i];
                    } else {
                        valueString += value.split(",")[i] + "和";
                    }
                }
            }
            //用例
            if (type.equals("input")) {
                stepLists.add("【" + name + "】输入框输入\"" + value + "\"，光标失焦");
                resultLists.add("【" + name + "】输入框输入成功，成功回显\"" + value + "\"" + "，无校验提示");
            } else if (type.equals("radio")) {
                stepLists.add("【" + name + "】单选框选中\"" + value + "\"选项");
                resultLists.add("【" + name + "】单选框成功选中\"" + value + "\"选项，其他选项全部未选中，无校验提示");
            } else if (type.equals("checkbox")) {
                stepLists.add("【" + name + "】复选框选中\"" + valueString + "\"选项");
                resultLists.add("【" + name + "】复选框成功选中\"" + valueString + "\"选项，其他选项全部未选中，无校验提示");
            } else if (type.equals("inputNumber")) {
                stepLists.add("【" + name + "】计数框输入\"" + value + "\"，光标失焦");
                resultLists.add("输入成功，【" + name + "】计数框回显\"" + value + "\"" + ",无校验提示");
            } else if (type.equals("select")) {
                stepLists.add("【" + name + "】下拉框选中\"" + valueString + "\"选项");
                resultLists.add("【" + name + "】下拉框成功选中\"" + valueString + "\"选项。查看下拉框，下拉框的值高亮\"" + valueString + "\"选项，无校验提示");
            } else if (type.equals("cascader")) {
                stepLists.add("【" + name + "】级联选择器选中\"" + valueString + "\"选项");
                resultLists.add("【" + name + "】级联选择器成功选中\"" + valueString + "\"选项。查看级联选择器，级联选择器的值高亮\"" + valueString + "\"选项，无校验提示");
            } else if (type.equals("datePicker")) {
                Date date = new Date();  //获取当前时间
                simpleDateFormat.applyPattern("yyyy-MM-dd");
                try {
                    if (restriction != false & !singleDate.equals("")) {
                        date = simpleDateFormat.parse(singleDate);
                        if (comparator.equals(">")) {
                            date = new Date(date.getTime() + 24 * 60 * 60 * 1000); //后一天
                        } else if (comparator.equals("<")) {
                            date = new Date(date.getTime() - 24 * 60 * 60 * 1000); //前一天
                        }
                    } else if (restriction != false & datePicker.size() > 0) {
                        date = simpleDateFormat.parse(String.valueOf(datePicker.get(1)));
                        date = new Date(date.getTime() - 24 * 60 * 60 * 1000); //前一天
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                stepLists.add(String.format("【" + name + "】日期选择器选择\"%s\"", simpleDateFormat.format(date)));
                resultLists.add(String.format("【" + name + "】日期选择器成功选中\"%s\"。查看日期选择器面板，面板高亮选中的值，无校验提示", simpleDateFormat.format(date)));
            } else if (type.equals("timePicker")) {
                Date date = new Date();  //获取当前时间
                simpleDateFormat.applyPattern("yyyy-MM-dd HH:mm:ss");  //其中的a时am和pm的标记，如果不加a则不会显示是上午还是下午
                try {
                    if (restriction != false & !singleTime.equals("")) {
                        date = simpleDateFormat.parse(singleTime.substring(0, 10) + " " + singleTime.substring(11, 19));
                        if (comparator.equals(">")) {
                            date = new Date(date.getTime() + 24 * 60 * 60 * 1000); //后一天
                        } else if (comparator.equals("<")) {
                            date = new Date(date.getTime() - 24 * 60 * 60 * 1000); //前一天
                        }
                    } else if (restriction != false & timePicker.size() > 0) {
                        date = simpleDateFormat.parse(String.valueOf(timePicker.get(1)).substring(0, 10) + " " + String.valueOf(timePicker.get(1)).substring(11, 19));
                        date = new Date(date.getTime() - 24 * 60 * 60 * 1000); //前一天
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                stepLists.add(String.format("【" + name + "】时间选择器选择\"%s\"", simpleDateFormat.format(date)));
                resultLists.add(String.format("【" + name + "】日期时间选择器成功选中\"%s\"。查看时间选择器面板，面板高亮选中的值，无校验提示", simpleDateFormat.format(date)));
            } else if (type.equals("upload")) {
                stepLists.add(String.format("【" + name + "】上传一个\".%s 文件，文件大小为%.1f Mb\"", fileFormat.get(0), fileSize - 0.1));
                resultLists.add("上传成功，无校验提示，已上传的列表显示该文件");
            }
        });
        if (operateId.equals("1")) {
            stepLists.add("点击\"" + btnName + "\"按钮");
            resultLists.add("1.成功关闭" + functionName + "对话框\n2.显示类似操作成功的消息提示\n3.列表刷新，添加的数据在列表首行显示\n4.数据库表新增一条记录");
            map.put("caseName", functionName + "_合法参数_正常新建");
        } else {
            stepLists.add("点击\"" + btnName + "\"按钮");
            resultLists.add("1.成功关闭" + functionName + "对话框\n2.显示类似操作成功的消息提示\n3.列表刷新，编辑的数据在列表首行显示\n4.数据库表更新记录");
            map.put("caseName", functionName + "_合法参数_正常编辑");
        }
        ArrayList<String> preconditionList = new ArrayList<>();
        map.put("precondition", preconditionList);
        map.put("step", stepLists);
        map.put("result", resultLists);
        if (stepLists.size() > 0 & preconditionList.size() > 0) {
            lists.add(map);
        }
        return lists;
    }

    /**
     * @param infoObj 表单对象
     * @return 删除操作用例
     */
    public ArrayList<HashMap<String, Object>> deleteOperation(JSONObject infoObj, JSONObject deleteOperationObj) {
        ArrayList<HashMap<String, Object>> lists = new ArrayList<>();
        String name = infoObj.getString("name");
        String btnName = infoObj.getString("btnName");
        if (deleteOperationObj.getString("type").equals("1")) {
            ArrayList<String> caseNameLists = new ArrayList<>();
            caseNameLists.add(name + "_单个删除_无引用关系_能删除");
            caseNameLists.add(name + "_单个删除_有引用关系_能删除");
            caseNameLists.add(name + "_单个删除_有引用关系_不能删除");
            for (int i = 0; i < caseNameLists.size(); i++) {
                HashMap<String, Object> map = new HashMap<>();
                ArrayList<String> stepLists = new ArrayList<>();
                ArrayList<String> resultLists = new ArrayList<>();
                ArrayList<String> preconditionList = new ArrayList<>();
                if (i == 0) {
                    if (!deleteOperationObj.getBoolean("isContact")) {
                        preconditionList.add("\n3.列表存在数据，无引用关系能删除");
                        stepLists.add("点击\"" + name + "\"按钮");
                        resultLists.add("1.成功打开删除确认框\n2.确认框内显示删除提示\"" + deleteOperationObj.getString("prompt") + "\"");
                        stepLists.add("点击\"" + btnName + "\"按钮");
                        resultLists.add("1.成功关闭删除确认框\n2.列表刷新，列表查询不到删除项\n3.数据库表中查询不到删除项或者更新了删除标记");
                    }
                } else if (i == 1) {
                    if (deleteOperationObj.getBoolean("isContact") & deleteOperationObj.getBoolean("isCanStill")) {
                        preconditionList.add("\n3.列表存在数据，有引用关系能删除");
                        stepLists.add("点击\"" + name + "\"按钮");
                        resultLists.add("1.成功打开删除确认框\n2.确认框内显示删除提示\"" + deleteOperationObj.getString("contactPrompt") + "\"");
                        stepLists.add("点击\"" + btnName + "\"按钮");
                        resultLists.add("1.成功关闭删除确认框\n2.列表刷新，列表查询不到删除项\n3.数据库表中查询不到删除项或者更新了删除标记\n4.有引用关系的数据根据需求决定是否联动删除");
                    }
                } else if (i == 2) {
                    if (deleteOperationObj.getBoolean("isContact") & !deleteOperationObj.getBoolean("isCanStill")) {
                        preconditionList.add("\n3.列表存在数据，有引用关系不能删除");
                        stepLists.add("点击\"" + name + "\"按钮");
                        resultLists.add("1.成功打开删除确认框\n2.确认框内显示删除提示\"" + deleteOperationObj.getString("contactPrompt") + "\"");
                        stepLists.add("点击\"" + btnName + "\"按钮");
                        resultLists.add("1.成功关闭删除确认框\n2.列表数据无变化");
                    }
                }
                map.put("caseName", caseNameLists.get(i));
                map.put("precondition", preconditionList);
                map.put("step", stepLists);
                map.put("result", resultLists);
                if (stepLists.size() > 0 & preconditionList.size() > 0) {
                    lists.add(map);
                }
            }
        } else {
            ArrayList<String> caseNameLists = new ArrayList<>();
            caseNameLists.add(name + "_批量删除_无引用关系_能删除");
            caseNameLists.add(name + "_批量删除_有引用关系_能删除");
            caseNameLists.add(name + "_批量删除_有引用关系_不能删除");
            caseNameLists.add(name + "_批量删除_未选中多选按钮直接点删除");
            for (int i = 0; i < caseNameLists.size(); i++) {
                HashMap<String, Object> map = new HashMap<>();
                ArrayList<String> stepLists = new ArrayList<>();
                ArrayList<String> resultLists = new ArrayList<>();
                ArrayList<String> preconditionList = new ArrayList<>();
                if (i == 0) {
                    if (!deleteOperationObj.getBoolean("isContact")) {
                        preconditionList.add("\n3.列表存在数据，无引用关系能删除");
                        stepLists.add("选中\"" + "多个CheckBox删除项\"按钮");
                        resultLists.add("选中成功");
                        stepLists.add("点击\"" + name + "\"按钮");
                        resultLists.add("1.成功打开删除确认框\n2.确认框内显示删除提示\"" + deleteOperationObj.getString("prompt") + "\"");
                        stepLists.add("点击\"" + btnName + "\"按钮");
                        resultLists.add("1.成功关闭删除确认框\n2.列表刷新，列表查询不到删除项\n3.数据库表中查询删除不到删除项或者更新了删除标记");
                    }
                } else if (i == 1) {
                    if (deleteOperationObj.getBoolean("isContact") & deleteOperationObj.getBoolean("isCanStill")) {
                        preconditionList.add("\n3.列表存在数据，有引用关系能删除");
                        stepLists.add("点击\"" + name + "\"按钮");
                        resultLists.add("1.成功打开删除确认框\n2.确认框内显示删除提示\"" + deleteOperationObj.getString("contactPrompt") + "\"");
                        stepLists.add("点击\"" + btnName + "\"按钮");
                        resultLists.add("1.成功关闭删除确认框\n2.列表刷新，列表查询不到删除项\n3.数据库表中查询删除不到删除项或者更新了删除标记\n4.有引用关系的数据根据需求决定是否联动删除");
                    }
                } else if (i == 2) { //_批量删除_有引用关系_不能删除
                    if (deleteOperationObj.getBoolean("isContact") & !deleteOperationObj.getBoolean("isCanStill")) {
                        preconditionList.add("\n3.列表存在数据，有引用关系不删除");
                        stepLists.add("点击\"" + name + "\"按钮");
                        resultLists.add("1.成功打开删除确认框\n2.确认框内显示删除提示\"" + deleteOperationObj.getString("contactPrompt") + "\"");
                        stepLists.add("点击\"" + btnName + "\"按钮");
                        resultLists.add("1.成功关闭删除确认框\n2.列表数据无变化");
                    }
                } else if (i == 3) { //_批量删除_未选中多选按钮直接点删除
                    if (deleteOperationObj.getBoolean("isContact") & !deleteOperationObj.getBoolean("isCanStill")) {
                        preconditionList.add("\n3.列表存在数据");
                        stepLists.add("未选中多选按钮直接点击\"" + name + "\"按钮");
                        resultLists.add("前端提示\"请选择一条记录\"，或" + name + "按钮置灰");
                    }
                }
                map.put("precondition", preconditionList);
                map.put("caseName", caseNameLists.get(i));
                map.put("step", stepLists);
                map.put("result", resultLists);
                if (stepLists.size() > 0 & preconditionList.size() > 0) {
                    lists.add(map);
                }
            }
        }
        ArrayList<String> stepLists = new ArrayList<>();
        ArrayList<String> resultLists = new ArrayList<>();
        ArrayList<String> preconditionLists = new ArrayList<>();
        String isContact = deleteOperationObj.getBoolean("isContact") ? "有" : "无";
        String isCanStill = deleteOperationObj.getBoolean("isCanStill") ? "能" : "不能";
        preconditionLists.add(String.format("\n3.列表存在数据，%s引用关系%s删除", isContact, isCanStill));
        stepLists.add("点击\"" + name + "\"按钮");
        resultLists.add("1.成功打开删除确认框\n2.确认框内显示删除提示\"" + (!deleteOperationObj.getString("contactPrompt").equals("") ? deleteOperationObj.getString("contactPrompt") : deleteOperationObj.getString("prompt")) + "\"");
        stepLists.add("点击\"取消\"按钮或\"右上角x\"按钮");
        resultLists.add("1.成功关闭删除确认框\n2.列表数据无变化");
        HashMap<String, Object> map = new HashMap<>();
        map.put("precondition", preconditionLists);
        map.put("caseName", name + "_取消删除");
        map.put("step", stepLists);
        map.put("result", resultLists);
        if (stepLists.size() > 0 & preconditionLists.size() > 0) {
            lists.add(map);
        }
        return lists;
    }

    /**
     * @param functionName 功能名称
     * @param searchObj    查询操作对象
     * @return 列表查询用例
     */
    public ArrayList<HashMap<String, Object>> listSearch(String functionName, JSONArray searchObj) {
        ArrayList<HashMap<String, Object>> lists = new ArrayList<>();
        ArrayList<String> caseNameList = new ArrayList<>();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
        String precondition = "\n3.列表存在%s\"的数据\n4.列表不存在%s\"的数据";
        String precondition1 = "\n3.列表存在%s等于\"%s\"的数据\n4.列表不存在%s列等于\"%s\"的数据";
        String step = "【%s】检索%s\"%s，点击\"查询\"按钮";
        String result = "查询成功，列表显示%s的所有数据";
        String result1 = "查询成功，列表显示暂无数据默认提示";
        searchObj.forEach(item -> {
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(item));
            String name = jsonObject.getString("name");
            String value = jsonObject.getString("value");
            String noValue = jsonObject.getString("noValue");
            String type = jsonObject.getString("type");
            String rule = jsonObject.getString("rule");
            HashMap<String, Object> map = new HashMap<>();
            String caseName = "";
            if (name.split(",").length > 1) {
                caseName = functionName + "_列表检索_多个查询字段_(" + name.replace(",", "、") + ")";
            } else {
                caseName = functionName + "_列表检索_单个查询字段_" + name;
            }
            caseNameList.add(caseName);
            map.put("caseName", caseName);
            ArrayList<String> preconditionList = new ArrayList<>();
            ArrayList<String> stepList = new ArrayList<>();
            ArrayList<String> resultList = new ArrayList<>();
            String stepContent = "";
            String stepContent1 = "";
            String resultContent = "";
            if (type.equals("input")) {
                String a = "";
                for (int i = 0; i < name.split(",").length; i++) {
                    a += name.split(",")[i] + "包含\"" + value + "\"";
                    if (i != name.split(",").length - 1) {
                        a += " 或 ";
                    }
                }
                System.out.println("a = " + a);
                if (rule.equals("2")) {
                    preconditionList.add(String.format(precondition
                            , a.replace(",", "或").substring(0, a.length() - 1)
                            , a.replace("包含\"" + value, "包含\"" + noValue).replace(",", "或").substring(0, a.replace("包含\"" + value, "包含\"" + noValue).length() - 1)));
                    stepContent = value.replace(",", "或") + "\"";
                    resultContent = a.replace(",", "或");
                    stepContent1 = noValue.replace(",", "或") + "\"";
                } else {
                    preconditionList.add(String.format(precondition
                            , a.replace(",", "或").replace("包含", "等于").substring(0, a.length() - 1)
                            , a.replace("包含\"" + value, "等于\"" + noValue).replace(",", "或").substring(0, a.replace("包含\"" + value, "等于\"" + noValue).length() - 1)));
                    stepContent = value.replace(",", "或") + "\"";
                    resultContent = a.replace("包含", "等于").replace(",", "或");
                    stepContent1 = noValue.replace(",", "或") + "\"";
                }
            } else if (type.equals("radio") | type.equals("checkbox") | type.equals("select") | type.equals("cascader")) {
                String preconditionString = "";
                for (int i = 0; i < value.split(",").length; i++) {
                    preconditionString += value.split(",")[i] + "\"或\"";
                }
                String preconditionString1 = "";
                for (int i = 0; i < noValue.split(",").length; i++) {
                    preconditionString1 += noValue.split(",")[i] + "\"或\"";
                }
                preconditionList.add(String.format(precondition1, name, preconditionString.substring(0, preconditionString.length() - 3),
                        name, preconditionString1.substring(0, preconditionString1.length() - 3)));
                stepContent = preconditionString.substring(0, preconditionString.length() - 3).replace("或", "和") + "\"选项";
                resultContent = name + "等于\"" + preconditionString.substring(0, preconditionString.length() - 3) + "\"";
                stepContent1 = preconditionString1.substring(0, preconditionString1.length() - 3).replace("或", "和") + "\"选项";
            } else if (type.equals("datePicker")) {
                JSONArray timePicker = jsonObject.getJSONArray("datePicker");
                simpleDateFormat.applyPattern("yyyy-MM-dd");
                try {
                    Date startDate = simpleDateFormat.parse((String) timePicker.get(0));
                    Date endDate = simpleDateFormat.parse((String) timePicker.get(1));
                    Date preDate = new Date(startDate.getTime() - 24 * 60 * 60 * 1000); //前一天
                    Date preDate1 = new Date(startDate.getTime() - 24 * 60 * 60 * 2000); //前一天
                    preconditionList.add("\n3.列表存在" + name + "在[" + simpleDateFormat.format(startDate) + " ~ " + simpleDateFormat.format(endDate) + "]范围内的数据" +
                            "\n4.列表不存在" + name + "在[" + simpleDateFormat.format(startDate) + " ~ " + simpleDateFormat.format(endDate) + "]范围外的数据");
                    stepContent = simpleDateFormat.format(startDate) + " ~ " + simpleDateFormat.format(endDate) + "\"";
                    resultContent = name + "在[" + simpleDateFormat.format(startDate) + " ~ " + simpleDateFormat.format(endDate) + "]范围内";
                    stepContent1 = simpleDateFormat.format(preDate1) + " ~ " + simpleDateFormat.format(preDate) + "\"";
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            } else if (type.equals("timePicker")) {
                JSONArray timePicker = jsonObject.getJSONArray("timePicker");
                simpleDateFormat.applyPattern("yyyy-MM-dd HH:mm:ss");
                String startTime = String.valueOf(timePicker.get(0)).substring(0, 10) + " " + String.valueOf(timePicker.get(0)).substring(11, 19);
                String endTime = String.valueOf(timePicker.get(1)).substring(0, 10) + " " + String.valueOf(timePicker.get(1)).substring(11, 19);
                try {
                    Date date = simpleDateFormat.parse(startTime);
                    Date preDate = new Date(date.getTime() - 24 * 60 * 60 * 1000); //前一天
                    Date preDate1 = new Date(date.getTime() - 24 * 60 * 60 * 2000); //前一天
                    preconditionList.add("\n3.列表存在" + name + "在[" + startTime + " ~ " + endTime + "]范围内的数据" +
                            "\n4.列表不存在" + name + "在[" + startTime + " ~ " + endTime + "]范围外的数据");
                    stepContent = startTime + " ~ " + endTime + "\"";
                    resultContent = name + "在[" + startTime + " ~ " + endTime + "]范围内";
                    stepContent1 = simpleDateFormat.format(preDate1) + " ~ " + simpleDateFormat.format(preDate) + "\"";
                } catch (ParseException e) {
                    e.printStackTrace();
//                    log.error(e.toString());
                }
            }
            stepList.add(String.format(step, name, mappingLabel(type), stepContent));
            resultList.add(String.format(result, resultContent));
            stepList.add(String.format(step, name, mappingLabel(type), stepContent1));
            resultList.add(result1);
            map.put("precondition", preconditionList);
            map.put("step", stepList);
            map.put("result", resultList);
            if (stepList.size() > 0 & preconditionList.size() > 0) {
                lists.add(map);
            }
        });
        caseNameList.add(functionName + "_列表检索_默认查询");
        ArrayList<String> preconditionList = new ArrayList<>();
        ArrayList<String> stepList = new ArrayList<>();
        ArrayList<String> resultList = new ArrayList<>();
        HashMap<String, Object> map = new HashMap<>();
        preconditionList.add("\n3.列表存在数据");
        stepList.add("没有输入或选择任何检索项，点击\"查询\"按钮");
        resultList.add(result1);
        map.put("caseName", functionName + "_列表检索_默认查询");
        map.put("precondition", preconditionList);
        map.put("step", stepList);
        map.put("result", resultList);
        if (stepList.size() > 0 & preconditionList.size() > 0) {
            lists.add(map);
        }
        return lists;
    }

    /**
     * @param functionName 功能名称
     * @param sortObj      排序对象
     * @return 排序用例
     */
    public ArrayList<HashMap<String, Object>> listSort(String functionName, JSONArray sortObj) {
        ArrayList<HashMap<String, Object>> lists = new ArrayList<>();
        ArrayList<String> caseNameLists = new ArrayList<>();
        ArrayList<String> stepLists = new ArrayList<>();
        ArrayList<String> resultLists = new ArrayList<>();
        ArrayList<String> preconditionList = new ArrayList<>();
        sortObj.forEach(item -> {
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(item));
            String name = jsonObject.getString("name");
            caseNameLists.add(functionName + "_列表排序_按" + name + "升序");
            stepLists.add("点击\"" + name + "升序\"按钮");
            resultLists.add("排序成功，列表数据优先按" + name + "升序排列显示");
            caseNameLists.add(functionName + "_列表排序_按" + name + "降序");
            stepLists.add("点击\"" + name + "降序\"按钮");
            resultLists.add("排序成功，列表数据优先按" + name + "降序排列显示");
            preconditionList.add("\n3.列表存在数据");
        });
        for (int i = 0; i < caseNameLists.size(); i++) {
            HashMap<String, Object> map = new HashMap<>();
            ArrayList<String> stepList = new ArrayList<>();
            ArrayList<String> resultList = new ArrayList<>();
            map.put("caseName", caseNameLists.get(i));
            map.put("precondition", preconditionList);
            stepList.add(stepLists.get(i));
            resultList.add(resultLists.get(i));
            map.put("step", stepList);
            map.put("result", resultList);
            if (stepList.size() > 0 & preconditionList.size() > 0) {
                lists.add(map);
            }
        }
        return lists;
    }

    /**
     * @param functionName 功能名称
     * @return 列表分页用例
     */
    public ArrayList<HashMap<String, Object>> listPaging(String functionName) {
        ArrayList<HashMap<String, Object>> lists = new ArrayList<>();
        ArrayList<String> caseNameList = new ArrayList<>();
        caseNameList.add(functionName + "_列表分页_查看表格内容");
        caseNameList.add(functionName + "_列表分页_列表无数据");
        caseNameList.add(functionName + "_列表分页_列表只有一页数据");
        caseNameList.add(functionName + "_列表分页_有多页数据_当前页为首页");
        caseNameList.add(functionName + "_列表分页_有多页数据_当前页为中间页");
        caseNameList.add(functionName + "_列表分页_有多页数据_当前页为尾页");
        caseNameList.add(functionName + "_列表分页_输入页码_跳转页");
        for (int i = 0; i < caseNameList.size(); i++) {
            ArrayList<String> preconditionList = new ArrayList<>();
            ArrayList<String> stepList = new ArrayList<>();
            ArrayList<String> resultList = new ArrayList<>();
            HashMap<String, Object> map = new HashMap<>();
            if (i == 0) {
                preconditionList.add("\n3.列表存在数据");
                stepList.add("查看列表表格内容显示");
                resultList.add("1.列表字段显示与原型一致\n2.列表数据过长显示...\n3.列表默认按创建时间倒序排列\n4.列表无默认检索条件，显示全部数据");
            } else if (i == 1) {
                preconditionList.add("\n3.列表不存在数据");
                stepList.add("查看列表以及分页控件");
                resultList.add("1.列表数据共0条，提示“暂无数据”\n" +
                        "2.上一页、下一页按钮，置灰不可点击\n" +
                        "3.页数项只有1，当前页标记为1");
            } else if (i == 2) {
                preconditionList.add("\n3.列表只有一页数据");
                stepList.add("查看列表以及分页控件");
                resultList.add("1.上一页、下一页按钮，置灰不可点击\n" +
                        "2.页数项只有1，当前页标记为1\n" +
                        "3.共*条，数据条数统计正确");
            } else if (i == 3) {
                preconditionList.add("\n3.列表有多页数据，当前所在第一页");
                stepList.add("查看列表以及分页控件");
                resultList.add("1.上一页按钮置灰不可点击，下一页按钮可点击\n" +
                        "2.页数项展示从1~总页数值，当前页标记为1\n" +
                        "3.共*条，数据条数统计正确");
            } else if (i == 4) {
                preconditionList.add("\n3.列表有多页数据，当前页所在中间页");
                stepList.add("查看列表以及分页控件");
                resultList.add("1.上一页、下一页按钮，可点击\n" +
                        "2.页数项展示从1~总页数值，当前页标记为所在页数值\n" +
                        "3.共*条，数据条数统计正确");
            } else if (i == 5) {
                preconditionList.add("\n3.列表有多页数据，当前所在尾页");
                stepList.add("查看列表以及分页控件");
                resultList.add("1.上一页按钮可点击，下一页按钮置灰不可点击\n" +
                        "2.页数项展示从1~总页数值，当前页标记为最大页数值\n" +
                        "3.共*条，数据条数统计正确");
            } else if (i == 6) {
                preconditionList.add("\n3.列表有多页数据");
                stepList.add("输入非数字字符，按回车键");
                resultList.add("输入框清空，不会跳转");
                stepList.add("输入小于1的小数，按回车键");
                resultList.add("自动变为1，跳转至第一页");
                stepList.add("输入大于1的小数，按回车键");
                resultList.add("取整数部分，跳转至该页");
                stepList.add("输入大于总页数，按回车键");
                resultList.add("跳转至尾页");
            }
            map.put("caseName", caseNameList.get(i));
            map.put("precondition", preconditionList);
            map.put("step", stepList);
            map.put("result", resultList);
            if (stepList.size() > 0 & preconditionList.size() > 0) {
                lists.add(map);
            }
        }
        return lists;
    }

    /**
     * @param startStopObj 启停对象
     * @param infoObj      基本信息对象
     * @return 启停用例
     */
    public ArrayList<HashMap<String, Object>> startStopOperation(JSONObject infoObj, JSONObject startStopObj) {
        String functionName = infoObj.getString("name");
        String btnName = infoObj.getString("btnName");
        ArrayList<HashMap<String, Object>> lists = new ArrayList<>();
        ArrayList<String> caseNameList = new ArrayList<>();
        caseNameList.add("启用" + functionName + "_无二次确认");
        caseNameList.add("启用" + functionName + "_有二次确认");
        caseNameList.add("停用" + functionName + "_有二次确认");
        caseNameList.add("停用" + functionName + "_无二次确认");
        for (int i = 0; i < caseNameList.size(); i++) {
            HashMap<String, Object> map = new HashMap<>();
            ArrayList<String> stepList = new ArrayList<>();
            ArrayList<String> resultList = new ArrayList<>();
            ArrayList<String> preconditionList = new ArrayList<>();
            map.put("caseName", caseNameList.get(i));
            if (i == 0) {
                if (!startStopObj.getBoolean("isStartConfirm")) {
                    preconditionList.add("\n3.启用时没有二次确认");
                    stepList.add("点击\"启用\"按钮");
                    resultList.add("1.显示类似操作成功的消息提示\n2.状态显示为启用中");
                }
            } else if (i == 1) {
                if (startStopObj.getBoolean("isStartConfirm")) {
                    preconditionList.add("\n3.启用时有二次确认");
                    stepList.add("点击\"启用\"按钮");
                    resultList.add(String.format("1.成功打开启用对话框\n2.对话框内显示提示\"%s\"", startStopObj.getString("startupPrompt")));
                    stepList.add(String.format("点击\"%s\"按钮", btnName));
                    resultList.add("1.成功关闭启用对话框\n2.显示类似操作成功的消息提示\n3.状态显示为启用中");
                }
            } else if (i == 2) {
                if (startStopObj.getBoolean("isStopConfirm")) {
                    preconditionList.add("\n3.停用时有二次确认");
                    stepList.add("点击\"启用\"按钮");
                    resultList.add(String.format("1.成功打开停用对话框\n2.对话框内显示提示\"%s\"", startStopObj.getString("stopPrompt")));
                    stepList.add(String.format("点击\"%s\"按钮", btnName));
                    resultList.add("1.成功关闭停用对话框\n2.显示类似操作成功的消息提示\n3.状态显示为停用中");
                }
            } else if (i == 3) {
                if (!startStopObj.getBoolean("isStopConfirm")) {
                    preconditionList.add("\n3.停用时没有二次确认");
                    stepList.add("点击\"停用\"按钮");
                    resultList.add("1.显示类似操作成功的消息提示\n2.状态显示为停用中");
                }
            }
            map.put("precondition", preconditionList);
            map.put("step", stepList);
            map.put("result", resultList);
            if (stepList.size() > 0 & preconditionList.size() > 0) {
                lists.add(map);
            }
        }
        return lists;
    }

    /**
     * @param module 所属模块
     * @param lists  所有用例
     * @param level  用例等级
     * @return minder结构数据
     */
    public JSONObject generateMinderData(String module, ArrayList<HashMap<String, Object>> lists, String level, String preconditionStr, String otherConditions) {
        String root = String.format("{\"root\": {\"data\": {\"text\": \"%s\",\"id\": \"0\"},\"children\": []},\"template\": \"right\",\"theme\": \"classic-compact\",\"version\": \"1.4.43\"}", module);
        String caseNode = "{\"data\":{\"text\":\"\",\"id\":\"\",\"resource\":[\"用例\"]},\"children\":[]}";
        String preconditionNode = "{\"data\":{\"text\":\"\",\"id\":\"\",\"resource\":[\"前置条件\"]},\"children\":[]}";
        String stepNode = "{\"data\":{\"text\":\"\",\"id\":\"\"},\"children\":[]}";
        JSONObject rootObj = JSONObject.parseObject(root);
//        System.out.println(JSON.toJSONString(lists));
        lists.forEach(item -> {
            JSONObject caseNodeObj = JSONObject.parseObject(caseNode);
            JSONObject preconditionNodeObj = JSONObject.parseObject(preconditionNode);
            JSONObject itemObj = JSONObject.parseObject(JSON.toJSONString(item));
            // 前置条件节点，公共前置条件 + 个别用例独有的条件 + 其他条件
            String precondition = preconditionStr + itemObj.getJSONArray("precondition").get(0).toString();
            Integer serialNumber = Integer.parseInt(precondition.split("\n")[precondition.split("\n").length - 1].substring(0, 1)) + 1;
            precondition = !otherConditions.equals("") ? precondition += ("\n" + serialNumber + "." + otherConditions) : precondition;
            preconditionNodeObj.getJSONObject("data").put("text", precondition);

            preconditionNodeObj.getJSONObject("data").put("id", UUID.randomUUID());
            caseNodeObj.getJSONArray("children").add(preconditionNodeObj);
            caseNodeObj.getJSONObject("data").put("priority", level);
            // 步骤节点
            for (int i = 0; i < itemObj.getJSONArray("result").size(); i++) {
                JSONObject stepNodeObj = JSONObject.parseObject(stepNode);
                JSONObject resultNodeObj = JSONObject.parseObject(stepNode);
                // 结果节点
                resultNodeObj.getJSONObject("data").put("text", itemObj.getJSONArray("result").get(i));
                resultNodeObj.getJSONObject("data").put("data", UUID.randomUUID());
                stepNodeObj.getJSONArray("children").add(resultNodeObj);
                // 步骤节点
                stepNodeObj.getJSONObject("data").put("text", itemObj.getJSONArray("step").get(i));
                stepNodeObj.getJSONObject("data").put("id", UUID.randomUUID());
                caseNodeObj.getJSONArray("children").add(stepNodeObj);
            }
            // 用例节点
            caseNodeObj.getJSONObject("data").put("id", UUID.randomUUID());
            caseNodeObj.getJSONObject("data").put("text", itemObj.getString("caseName"));
//            caseNodeObj.getJSONObject("data").getJSONArray("resource").add(level);
            // 根节点
            rootObj.getJSONObject("root").getJSONArray("children").add(caseNodeObj);
        });

        return rootObj;
    }
}
